package myJs.user.centrifuge

import myJs.Utils._
import myJs.myPkg.jquery._
import myJs.myPkg._
import org.scalajs.dom._
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.raw.{Blob, BlobPropertyBag}
import scalatags.Text.all._
import scalatags.Text.{TypedTag, all}
import shared.VarTool

import scala.scalajs.js
import scala.scalajs.js.JSON
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import scala.concurrent.ExecutionContext.Implicits.global
import js.JSConverters._
import myJs.Implicits._
import myJs.tool.Pojo.FilterContentData
import myJs.tool.Tool

import scala.collection.immutable.SeqMap
import scala.scalajs.js.Dynamic.{global => g}

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("MissionResult")
object MissionResult {

  val tableId = "table"
  var reportTableRs: JArJDJAn = _

  @JSExport("init")
  def init = {
    refreshMissionInfo(Tool.getMissionId)
    initReportTable
    refreshStatInfo
    registerEvent
  }

  def refreshStatInfo={
    val missionId=Tool.getMissionId
    val url = g.jsRoutes.controllers.CentrifugeController.getStatInfo().url.toString
    Ajax.get(url = s"${url}?missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDS
      $("#statString").text(dict("str"))
    }
  }

  def registerEvent = {
    tableFilterEvent
  }

  def filterContentShow(y: Element) = {
    val prentJq = getParentJq(y)
    prentJq.find(s".filterContent").hide()
    val fieldName = Tool.getFilterDataFieldName(y)
    val contentJq = prentJq.find(s"#${fieldName}Content")
    val yTop = $(y).offset().top + $(y).height() + 3
    val pageWidth = document.body.clientWidth
    val yTotalLeft = $(y).offset().left
    val yLeft = yTotalLeft
    val width = 210
    val trueYLeft = if (yTotalLeft + width > pageWidth) pageWidth - 220 - 6 else yLeft
    contentJq.css("top", yTop.toInt).css("left", trueYLeft.toInt).width(width)
    contentJq.show()
    Tool.filterContentFillBeforeValue(contentJq)
  }

  def getParentJq(y: Element) = {
    $(y).parents(".table-responsive")
  }

  def tableFilterEvent = {
    Tool.clickHide

    $(document.body).on("click", s".myOperate", "", (y: Element) => {
      filterContentShow(y)
    })
    $(document.body).on("click", s".mySortLi", "", (y: Element) => {
      val parentJq = getParentJq(y)
      Tool.execSort(y, parentJq, () => {
        refreshTable(parentJq)
      })
    })
    $(document.body).on("click", s".myConfirm", "", (y: Element) => {
      val parentJq = getParentJq(y)
      Tool.confirmFilter(y, parentJq, () => {
        refreshTable(parentJq)
      })
    })
    $(document.body).on("click", s".myHide", "", (y: Element) => {
      Tool.hideFilterContent(y)
    })
    $(document.body).on("click", s".myRemove", "", (y: Element) => {
      val parentJq = getParentJq(y)
      Tool.removeCondition(y, parentJq, () => {
        refreshTable(parentJq)
      })
    })
    $(document.body).on("click", s".myRemoveSort", "", (y: Element) => {
      val parentJq = getParentJq(y)
      Tool.removeSort(y, parentJq, () => {
        refreshTable(parentJq)
      })
    })
  }

  def refreshTable(parentJq: JQuery): Any = {
    refreshTable(parentJq, () => ())
  }

  def getColumnV(columnName: String, v: js.Any) = columnName match {
    case _ =>
      v.toString
  }

  def refreshTable(parentJq: JQuery, f: () => Any): Any = {
    val queryMap = Tool.getQueryMap(parentJq)
    val tableRs = parentJq.idAttr match {
      case "report" => reportTableRs
    }
    val sortData = Tool.sortExec(tableRs, queryMap)
    val filterData = Tool.execFilter(sortData = sortData, queryMap = queryMap, getColumnV = getColumnV)
    parentJq.find(s"#${tableId}").bootstrapTable("load", filterData)
    f()
  }

  def initReportTable = {

    def initFilterContent(parentId: String, map: SeqMap[String, String]) = {
      val textSortDatas = map.take(3).map { case (k, v) =>
        FilterContentData(k, v)
      }.toList
      val rangeSortDatas = map.drop(3).map { case (k, v) =>
        FilterContentData(k, v)
      }.toList
      Tool.initFilterContent(textSortDatas = textSortDatas, rangeSortDatas = rangeSortDatas, parentId = s"${parentId}")
      textSortDatas ::: rangeSortDatas
    }

    val parentId = "report"
    val fileName = "report.txt"
    val url = g.jsRoutes.controllers.CentrifugeController.getFileData().url.toString
    Ajax.get(url = s"${url}?missionId=${getMissionId}&fileName=${fileName}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      val rs = xhr.responseText.toJDJAn
      val columnNames = rs("columnNames").toJArS
      val array = rs("array").toJArJDJAn
      reportTableRs = array
      val map = (columnNames.indices.map(_.toString)).zip(columnNames).toList.toSeqMap
      val allDatas = initFilterContent(parentId, map)
      val columns = array.head.keys.toList.map { index =>
        val columnName = columnNames(index.toInt)
        val basicOptions = ColumnOptions.field(index).sortable(true).title(columnName)
        columnName match {
          case x if allDatas.map(_.label).contains(x) => basicOptions.
            sortable(false).operateable(true)
          case _ => basicOptions
        }
      }.toJSArray
      val exportOptions = ExportOptions.fileName(fileName.fileNamePrefix).csvSeparator("\t").csvEnclosure("")
      val basicOptions = TableOptions.data(rs("array")).columns(columns).exportOptions(exportOptions).showExport(true).
        exportDataType("all").exportTypes(js.Array("txt")).pagination(true).
        pageList(js.Array("10", "25", "50", "100", "all")).locale("zh-CN")
      val options = if (columnNames.isEmpty) {
        basicOptions.showHeader(false)
      } else basicOptions
      $(s"#${parentId} #${tableId}").bootstrapTable(options)
    }
  }

  def refreshMissionInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.CentrifugeController.getMissionById().url.toString
    Ajax.get(url = s"${url}?missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDJAn
      dict.foreach { case (k, v) =>
        val trueV = k match {
          case x if x != "arg" => span(v.toString).render
          case x if x == "arg" => span().render
        }
        $(s"#mission #${k}").html(trueV)
        refreshArg(dict("arg"))
      }
    }
  }

  def refreshArg(arg: js.Any) = {
    val tableId = "argTable"
    val columnNames = List("参数名称","值")
    val columns = columnNames.map { columnName =>
      val fmt = columnName
      ColumnOptions.field(columnName).title(columnName).sortable(true)
    }.toJSArray
    val array = arg.toJDJAn.map { case (k, v) =>
      js.Dictionary("参数名称" -> k, "值" -> v)
    }.toJSArray
    val options = TableOptions.data(array).columns(columns).pagination(false)
    $(s"#${tableId}").bootstrapTable(options)
    if (array.isEmpty) {
      $("#arg").text("无").show()
      $(s"#${tableId}").hide()
    }
  }

  def getMissionId = {
    g.missionId.toString
  }

}
